package com.ruoyi.common.utils.http.ftp.pool;



import com.ruoyi.framework.config.FTPConfig;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.io.IOException;

public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {
    private static  final Logger logger = LoggerFactory.getLogger(FTPTemplate.class);
    private static final GenericObjectPool<FTPClient> ftpClientPool=new GenericObjectPool<>(new FTPClientFactory());
    public static  GenericObjectPool<FTPClient> getFtpClientPool() {
        return FTPClientFactory.ftpClientPool;
    }

    @Override
    public FTPClient create() throws Exception {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding(FTPConfig.getEncoding());
        ftpClient.setConnectTimeout(FTPConfig.getConnectTimeout());
        try {
            if(!ftpClient.isConnected()){
                ftpClient.connect(FTPConfig.getHost(),FTPConfig.getPort());
            }
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                logger.warn("FTPServer refused connection,replyCode:{}", replyCode);
                return null;
            }

            if (!ftpClient.login(FTPConfig.getUsername(), FTPConfig.getPassword())) {
                logger.warn("ftpClient login failed... username is {}; password: {}", FTPConfig.getUsername(), FTPConfig.getPassword());
            }

            ftpClient.setBufferSize(Integer.valueOf(FTPConfig.getBufferSize()));
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            if (FTPConfig.getPassiveMode()) {
                ftpClient.enterLocalPassiveMode();
            }

        } catch (IOException e) {
            logger.error("create ftp connection failed...", e);
        }
        return ftpClient;
    }

    @Override
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
        return new DefaultPooledObject<>(ftpClient);
    }

    @Override
    public void destroyObject(PooledObject<FTPClient> ftpPooled) throws Exception {
        if (ftpPooled == null) {
            return;
        }

        FTPClient ftpClient = ftpPooled.getObject();

        try {
            if (ftpClient.isConnected()) {
                ftpClient.logout();
            }
        } catch (IOException io) {
            logger.error("ftp client logout failed...{}", io);
        } finally {
            try {
                ftpClient.disconnect();
            } catch (IOException io) {
                logger.error("close ftp client failed...{}", io);
            }
        }
    }

    @Override
    public boolean validateObject(PooledObject<FTPClient> ftpPooled) {
        try {
            FTPClient ftpClient = ftpPooled.getObject();
            return ftpClient.sendNoOp();
        } catch (IOException e) {
            logger.error("Failed to validate client: {}", e);
        }
        return false;
    }
}
